/*
# File    :   cp_via_write_read_api.c
# Author  :   SCHIPS
# Mail    :   schips@dingtalk.com
# Date    :   Fri, May 17, 2019  2:56:37 PM
*/

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int file_wr_hard(const char * path_r, const char* path_w)
{
    int fd_r;
    int fd_w;

    ssize_t rd_size, wr_size;

    char buffer[4*1024];
    char *poffs;

    //printf("File IO\n");
    fd_r = open(path_r, O_RDONLY);
    fd_w = open(path_w, O_WRONLY|O_CREAT|O_TRUNC, 
                S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);

    if(fd_r == -1 )
    {
        return -1;
    }

    if(fd_w == -1)
    {
        close(fd_r);
        return -1;
    }

    while(1)
    {
        rd_size = read(fd_r, buffer, sizeof(buffer));
        if(rd_size == -1)
        {
            perror("read file error\n");
            goto err;
        }

        if(rd_size == 0)
            break;

        poffs = buffer;

        while(1)
        {
            wr_size = write(fd_w, poffs, rd_size); // 实际写入长度wr_size 只会小于或等于预设写入长度rd_size
            if(wr_size == -1)
            {
                perror("write to new file error\n");
                goto err;
            }

            if(wr_size == rd_size) // 当 实际写入长度 小于 预设写入长度，必须进行处理，以防丢包
                break;

            rd_size  -=  wr_size;

            poffs +=  wr_size;
        }	
    }

    close(fd_w);
    close(fd_r);

    return 0;

err:
    return -1;
}

int file_wr_soft(const char * path_r, const char* path_w)
{
    FILE * p_src = NULL;
    FILE * p_dest = NULL;

    char buf[100] = {0};

    int size = 0;

    //printf("Standard IO\n");
    p_src=fopen(path_r,"rb");

    if(!p_src)
    {
        return 0;
    } 

    p_dest = fopen(path_w, "wb");

    if(!p_dest)
    {
        fclose(p_src);
        p_src = NULL;
        return 0;
    }

    while(1)
    {
        size = fread(buf, sizeof(char), 100, p_src);
        if( !size ){ break; }
        fwrite(buf, sizeof(char), size, p_dest);
    }

    //从原始文件里拿到多少个数据，就写多少个数据。
    fclose(p_dest);
    fclose(p_src);
    p_dest = NULL;
    p_src = NULL;
    return 0;
}

int main(int argc, char *argv[])
{
    if(argc != 4)
    {
        return -1;
    }

    if(argv[3][0] != 'A')
    {
        file_wr_hard(argv[1],argv[2]);
    }else
    {
        file_wr_soft(argv[1],argv[2]);
    }

    return 0;
}
